﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Web;

using Concret;
using ORM;
using static Constants;
using static DataLogic;

public class CommonHDL : HandlerBase
{
	/// <summary>
	/// 移动目录或图片
	/// </summary>
	/// <param name="moved">被移动图片</param>
	/// <param name="to">目标目录下</param>
	/// <returns></returns>
	public dynamic move(Photo moved, Dir to)
	{
		if (moved == null || to == null) throw new Error("参数出错，请刷新页面后重新操作");

		var me = GetCurrentUser(DbOp);
		if (moved.User_Val != me && !me.IsAdmin()) throw new Error("你不是图片作者，也不是管理员");

		moved.Dir_Val = to;
		if (!moved.Update()) throw new Error("移动图片失败");

		return null;
	}

	/// <summary>
	/// 新建目录
	/// </summary>
	/// <param name="title"></param>
	/// <returns></returns>
	public dynamic addDir(string title)
	{
		if (new Dir(DbOp) { Title_Val = title }.GetByFVs().Any()) throw new Error("已经有同名的目录");

		var result = new Dir(DbOp)
		{
			Title_Val = title,
		}.Insert();

		if (result.HasValue) return result.Value; else throw new Error("新建目录失败");
	}

	/// <summary>
	/// 目录改名
	/// </summary>
	/// <param name="dir"></param>
	/// <param name="title"></param>
	/// <returns></returns>
	public dynamic modDir(Dir dir, string title)
	{
		dir.Title_Val = title;
		if (dir.Update()) return null; else throw new Error("目录改名失败");
	}

	/// <summary>
	/// 删除目录
	/// </summary>
	/// <param name="dir"></param>
	/// <returns></returns>
	public dynamic delDir(Dir dir)
	{
		if (dir == null) return null;

		if (dir.Dir__Photo().Any()) throw new Error("目录下有图片，不能删除");
		var result = dir.Delete();
		if (!result.ok) throw new Error("删除目录失败：" + result.err);

		return null;
	}

	/// <summary>
	/// 保存上传的文件
	/// </summary>
	/// <param name="dir"></param>
	/// <param name="files"></param>
	/// <returns></returns>
	public dynamic saveUpload(Dir dir, string files)
	{
		var me = GetCurrentUser(DbOp);
		var fileNamePaths = JsonSerializer.Deserialize<string[]>(files);
		var failed = new List<string>();
		foreach (var file in fileNamePaths)
		{
			Dir odir = dir;

			var parts = file.Split('|');

			try
			{
				var img = HttpContext.Current.Server.MapPath(parts[1]);
				using (var image = Image.FromFile(img))
				{
					var item = image.PropertyItems.SingleOrDefault(p => p.Id == 0x112);
					var rotate = item?.Value[0];
					if (rotate.HasValue)
					{
						switch (rotate)
						{
							//相当于无改变，但要动一动，否则后面image.Save会出错——WTF~~
							default: image.RotateFlip(RotateFlipType.RotateNoneFlipX); image.RotateFlip(RotateFlipType.RotateNoneFlipX); break;

							case 2: image.RotateFlip(RotateFlipType.RotateNoneFlipX); break;
							case 3: image.RotateFlip(RotateFlipType.Rotate180FlipNone); break;
							case 4: image.RotateFlip(RotateFlipType.RotateNoneFlipY); break;
							case 5: image.RotateFlip(RotateFlipType.Rotate90FlipX); break;
							case 6: image.RotateFlip(RotateFlipType.Rotate270FlipNone); break;
							case 7: image.RotateFlip(RotateFlipType.Rotate270FlipX); break;
							case 8: image.RotateFlip(RotateFlipType.Rotate90FlipNone); break;
						}
						item.Value[0] = 1;
						image.SetPropertyItem(item);
						image.Save(img);
					}

					if (!new Photo(DbOp) { User_Val = me, Dir_Val = dir, Title_Val = parts[0], Path_Val = parts[1] }.Insert().HasValue)
						failed.Add(parts[0]);
				}
			}
			catch { failed.Add(parts[0]); }

			Uploadings.TryRemove(parts[1], out var _);
		}

		if (failed.Count > 0) throw new Error("以下文件未能保存，也可能是图片已损坏\n" + failed.JoinBy("\n"));

		return null;
	}

	/// <summary>
	/// 设置图片备注
	/// </summary>
	/// <param name="photo"></param>
	/// <param name="remark"></param>
	/// <returns></returns>
	public dynamic modPhoto(Photo photo, string remark)
	{
		if (photo == null) throw new Error("图片不存在，请刷新页面检查");

		var me = GetCurrentUser(DbOp);
		if (photo.User_Val != me && !me.IsAdmin()) throw new Error("你不是此图片的作者，也不是管理员");

		photo.Remark_Val = remark == "" ? null : remark;
		if (photo.Update())
			notify(photo);
		else
			throw new Error("设置图片备注失败");

		return null;
	}

	/// <summary>
	/// 删除图片
	/// </summary>
	/// <param name="photo"></param>
	/// <returns></returns>
	public dynamic delPhoto(Photo photo)
	{
		if (photo == null) return null;

		var me = GetCurrentUser(DbOp);
		if (photo.User_Val != me && !me.IsAdmin()) throw new Error("你不是此图片的作者，也不是管理员");

		var dir = photo.Dir_Val;
		var file = HttpContext.Current.Server.MapPath(photo.Path_Val);
		var res = photo.Delete();
		if (res.ok)
		{
			try { File.Delete(file); File.Delete(file.Replace(@"\attachment\", @"\thumb\")); } catch { }
			return new { dir = dir.Id.ToString(), count = dir.Dir__Photo().Count() };
		}
		else
			throw new Error($"删除失败：{res.err}");
	}

	/// <summary>
	/// 修改当前用户密码
	/// </summary>
	/// <param name="psw"></param>
	/// <returns></returns>
	public dynamic password(string psw)
	{
		var user = GetCurrentUser(DbOp);
		if (user == null) throw new Error("用户未登录或登录状态失效，请重新登录");

		user.Password_Val = psw;
		if (!user.Update()) throw new Error("修改密码失败");

		Response.Cookies.Add(new HttpCookie("psw", psw));
		return null;
	}

	/// <summary>
	/// 通知前端更新图片显示
	/// </summary>
	/// <param name="photo"></param>
	void notify(Photo photo)
	{
		var disposed = new List<WebSocket>();

		AdvancedLock.EnterShareBlock(() =>
		{
			foreach (var socket in WebSockets)
				try
				{
					socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes($"photo:{photo.Id}:title:{photo.Remark_Val ?? photo.Title_Val}")), WebSocketMessageType.Text, true, CancellationToken.None);
				}
				catch
				{
					disposed.Add(socket);
				}
		});

		if (disposed.Count > 0)
			AdvancedLock.EnterMutexBlock(() => disposed.ForEach(socket => WebSockets.Remove(socket)));
	}
}